﻿using Fdb.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq.Expressions;
using System.Text;

namespace Fdb
{
    /// <summary>
    /// 通用逻辑类
    /// </summary>
    /// <typeparam name="T">泛型类</typeparam>
    public class Logic<T>
    {
        #region 连接字符串

        ///// <summary>
        ///// 连接字符串名称
        ///// </summary>
        //private string _ConnectionStringName = "ConnectionString";

        ///// <summary>
        ///// 连接字符串名称
        ///// </summary>
        //public string ConnectionStringName
        //{
        //    get { return _ConnectionStringName; }
        //    set { _ConnectionStringName = value; }
        //}

        /// <summary>
        /// 连接字符串
        /// </summary>
        private string _ConnectionString = "完整的连接字符串，支持不同数据库";

        /// <summary>
        /// 连接字符串
        /// </summary>
        public string ConnectionString
        {
            get { return _ConnectionString; }
            set { _ConnectionString = value; }
        }

        /// <summary>
        /// 数据库类型
        /// </summary>
        private DatabaseType _DatabaseType = DatabaseType.NO;

        /// <summary>
        /// 数据库类型
        /// </summary>
        public DatabaseType DatabaseType
        {
            get { return _DatabaseType; }
            set { _DatabaseType = value; }
        }

        #endregion 连接字符串

        /// <summary>
        /// 创建数据库
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="dbname"></param>
        /// <returns></returns>
        public ExecuteResult CreateDB(string connectionString, string dbname)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).CreateDB(connectionString, dbname);
            return er;
        }

        #region 获取数据库结构抽象方法

        /// <summary>
        /// 获取指定数据库下所有表信息
        /// </summary>
        /// <param name="dbname">数据库名称</param>
        /// <returns></returns>
        public List<TableClass> GetDbTableList(string dbname)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetDbTableList(dbname);
        }

        /// <summary>
        /// 获取指定数据库下指定表的所有字段信息
        /// </summary>
        /// <param name="dbname">数据库名称</param>
        /// <param name="tblname">表名称</param>
        /// <returns></returns>
        public List<FieldClass> GetTblFieldList(string dbname, string tblname)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetTblFieldList(dbname, tblname);
        }

        /// <summary>
        /// 获取指定数据库下所有表信息
        /// </summary>
        /// <param name="dbname">数据库名称</param>
        /// <returns></returns>
        public List<TableClass> GetDbTableListByConnString(string dbname, string dbtype)
        {
            this.DatabaseType = Get_DatabaseType(dbtype);
            return DBHandlerFactory.GetHandler2<T>(this.ConnectionString, this.DatabaseType).GetDbTableList(dbname);
        }

        /// <summary>
        /// 获取指定数据库下指定表的所有字段信息
        /// </summary>
        /// <param name="dbname">数据库名称</param>
        /// <param name="tblname">表名称</param>
        /// <returns></returns>
        public List<FieldClass> GetTblFieldListByConnString(string dbname, string dbtype, string tblname)
        {
            this.DatabaseType = Get_DatabaseType(dbtype);
            return DBHandlerFactory.GetHandler2<T>(this.ConnectionString, this.DatabaseType).GetTblFieldList(dbname, tblname);
        }

        /// <summary>
        /// 获取数据库
        /// </summary>
        /// <param name="dbtype"></param>
        /// <returns></returns>
        public DatabaseType Get_DatabaseType(string dbtype)
        {
            switch (dbtype)
            {
                case "sqlserver":
                    return DatabaseType.SqlServer;
                case "oracle":
                    return DatabaseType.Oracle;
                case "odbc":
                    return DatabaseType.ODBC;
                case "oledb":
                    return DatabaseType.OLEDB;
                case "sqlite":
                    return DatabaseType.SQLite;
                case "mysql":
                    return DatabaseType.Mysql;
                case "0":
                    return DatabaseType.NO;
            }

            return DatabaseType.NO;
        }

        #endregion 获取数据库结构抽象方法

        #region 表维护抽象方法

        /// <summary>
        /// 判断数据表是否存在
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public virtual bool IsTableExist(string tableName)
        {
            bool isExist = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).IsTableExist(tableName);
            return isExist;
        }

        /// <summary>
        /// 创建一个默认数据表
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        public ExecuteResult CreateTable(string tableName)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).CreateTable(tableName);
            return er;
        }

        /// <summary>
        /// 修改表名
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        public ExecuteResult ModifyTable(string oldTableName, string newTableName)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).ModifyTable(oldTableName, newTableName);
            return er;
        }

        /// <summary>
        /// 判断字段是否存在
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public bool IsFieldExist(FieldClass field)
        {
            bool res = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).IsFieldExist(field);
            return res;
        }

        /// <summary>
        /// 创建字段
        /// </summary>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public ExecuteResult CreateField(FieldClass field)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).CreateField(field);
            return er;
        }

        /// <summary>
        /// 删除字段
        /// </summary>
        /// <param name="field">字段</param>
        /// <returns></returns>
        public ExecuteResult DeleteField(FieldClass field)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).DeleteField(field);
            return er;
        }

        /// <summary>
        /// 修改字段
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        public ExecuteResult ModifyField(FieldClass oldField, FieldClass newField)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).ModifyField(oldField, newField);
            return er;
        }

        /// <summary>
        /// 根据实体类创建表
        /// </summary>
        /// <returns></returns>
        public ExecuteResult CreateTable()
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).CreateTable();
            return er;
        }

        /// <summary>
        ///  创建业务流程视图
        /// </summary>
        /// <param name="flowCode">流程编码</param>
        /// <param name="bizViewName">业务视图名称</param>
        /// <param name="primary">标识字段</param>
        /// <param name="datasouceSQL">业务数据源SQL</param>
        /// <returns></returns>
        public ExecuteResult CreateBizFlowView(string flowCode, string bizViewName, string primary, string datasouceSQL)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).CreateBizFlowView(flowCode, bizViewName, primary, datasouceSQL);
        }

        #endregion 表维护抽象方法

        #region 基础抽象方法

        /// <summary>
        /// 测试数据库连接
        /// </summary>
        /// <returns></returns>
        public ExecuteResult TestConnnection()
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).TestConnnection();
        }

        /// <summary>
        /// 根据SQL获取DataTable
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public DataTable FetchDataTable(string sql)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetDataTable(sql);
        }

        /// <summary>
        /// 根据参数化SQL获取DataTable
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public DataTable FetchDataTable(string sql, NHashtable ht)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetDataTable(sql, ht);
        }

        /// <summary>
        /// 根据存储过程获取DataTable对象
        /// </summary>
        /// <param name="storeProcName">存储过程名称</param>
        /// <returns></returns>
        public DataTable FetchDataTableWithStoreProc(string storeProcName)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetDataTableWithStoreProc(storeProcName);
        }

        /// <summary>
        /// 根据存储过程获取DataTable对象
        /// </summary>
        /// <param name="storeProcName">存储过程名称</param>
        /// <param name="ht">参数</param>
        /// <returns></returns>
        public DataTable FetchDataTableWithStoreProc(string storeProcName, NHashtable ht)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetDataTableWithStoreProc(storeProcName, ht);
        }

        /// <summary>
        /// 执行sql
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public ExecuteResult ExecuteSQLWithResult(string sql)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).ExecuteSQLWithResult(sql);
        }

        /// <summary>
        /// 执行事务sql
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="dbTransaction"></param>
        /// <returns></returns>
        public ExecuteResult ExecuteSQLWithTrans(string sql, DbTransaction dbTransaction)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType, dbTransaction).ExecuteSQLWithResult(sql);
            er.DbTransaction = dbTransaction;
            return er;
        }

        /// <summary>
        /// 执行sql
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="sql"></param>
        /// <returns></returns>
        public ExecuteResult ExecuteSQLWithConn(string conn, string sql)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).ExecuteSQLWithConn(conn, sql);
        }

        /// <summary>
        /// 执行参数化SQL
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="ht"></param>
        /// <returns></returns>
        public ExecuteResult ExecuteSQLWithResult(string sql, NHashtable ht)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).ExecuteSQLWithResult(sql, ht);
        }

        /// <summary>
        /// 执行事务
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="ht"></param>
        /// <returns></returns>
        public ExecuteResult ExcuteTransactionSQL(string sql, NHashtable ht)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).ExcuteTransactionSQL(sql, ht);
        }

        /// <summary>
        /// 获得单个object变量
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public object FetchDataObject(string sql)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetDataObject(sql);
        }

        /// <summary>
        /// 获得单个object变量
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public object FetchDataObject(string sql, NHashtable ht)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetDataObject(sql, ht);
        }

        /// <summary>
        /// 获取分页记录
        /// </summary>
        /// <param name="pagedQuery"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        public DataTable FetchDataTable(PagedQuery pagedQuery)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetDataTable(pagedQuery);
        }

        /// <summary>
        /// 获取分页记录
        /// </summary>
        /// <param name="pagedQuery"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        public int FetchCount(PagedQuery pagedQuery)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).GetCount(pagedQuery);
        }

        #endregion 基础操作方法

        #region 增删改抽象方法

        /// <summary>
        /// 添加新记录
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="ht"></param>
        /// <returns></returns>
        public ExecuteResult Insert(string tableName, NHashtable ht)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Insert(tableName, ht);
            return er;
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <returns></returns>
        public ExecuteResult Insert(T obj)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Insert(obj);
            return er;
        }

        /// <summary>
        /// 开启一个数据库事务对象
        /// </summary>
        /// <returns></returns>
        public ExecuteResult BeginTransaction()
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).BeginTransaction();
            return er;
        }

        /// <summary>
        /// 执行指定事务添加
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="dbTransaction"></param>
        /// <returns></returns>
        public ExecuteResult InsertWithTrans(T obj, DbTransaction dbTransaction)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType, dbTransaction).Insert(obj);
            return er;
        }

        /// <summary>
        /// 更新记录
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="ht"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public ExecuteResult Update(string tableName, NHashtable ht, string where)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Update(tableName, ht, where);
            return er;
        }

        /// <summary>
        ///  修改
        /// </summary>
        /// <returns></returns>
        public ExecuteResult Update(T obj)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Update(obj);
            return er;
        }

        /// <summary>
        /// 执行事务进行编辑
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="dbTransaction"></param>
        /// <returns></returns>
        public ExecuteResult UpdateWithTrans(T obj, DbTransaction dbTransaction)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType, dbTransaction).Update(obj);
            return er;
        }

        /// <summary>
        /// 写入数据库
        /// </summary>
        /// <returns></returns>
        public ExecuteResult WriteToDb(T obj)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).WriteToDb(obj);
            return er;
        }

        /// <summary>
        /// 按编号删除
        /// </summary>
        /// <returns></returns>
        public ExecuteResult Delete(int id)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Delete(id);
        }

        /// <summary>
        /// 按GUID删除
        /// </summary>
        /// <returns></returns>
        public ExecuteResult Delete(Guid guid)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Delete(guid);
        }

        /// <summary>
        /// 删除指定对象
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public ExecuteResult Delete(T t)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Delete(t);
        }

        /// <summary>
        /// 执行事务进行删除
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="dbTransaction"></param>
        /// <returns></returns>
        public ExecuteResult DeleteWithTrans(T obj, DbTransaction dbTransaction)
        {
            ExecuteResult er = DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType, dbTransaction).Delete(obj);
            return er;
        }

        #endregion 增删改抽象方法

        #region 泛型查询抽象方法
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <returns></returns>
        public T Fetch(long id)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Fetch(id);
        }

        /// <summary>
        /// 根据GUID获取单个对象
        /// </summary>
        /// <param name="guid"></param>
        /// <returns></returns>
        public T Fetch(Guid guid)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Fetch(guid);
        }

        /// <summary>
        /// 根据SQL获取单个对象
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public T Fetch(string sql)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Fetch(sql);
        }

        /// <summary>
        /// 根据SQL和查询参数获取单个对象
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="nht"></param>
        /// <returns></returns>
        public T Fetch(string sql, NHashtable nht)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Fetch(sql, nht);
        }

        /// <summary>
        /// 根据实体对象获取匹配对象
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        public T Fetch(T t)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Fetch(t);
        }

        /// <summary>
        /// 根据Lambda获取匹配对象
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public T Fetch(Expression<Func<T, bool>> where)
        {
            string sql = LambdaToSqlHelper.GetSqlFromExpression(where);
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).Fetch(sql);
        }

        /// <summary>
        /// 获取全部对象
        /// </summary>
        /// <returns></returns>
        public List<T> FetchList()
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchList();
        }

        /// <summary>
        /// 根据SQL获取对象列表
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public List<T> FetchList(string sql)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchList(sql);
        }

        /// <summary>
        /// 根据Lambda获取对象列表
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public List<T> FetchList(Expression<Func<T, bool>> where)
        {
            string sql = LambdaToSqlHelper.GetSqlFromExpression(where);
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchList(sql);
        }

        /// <summary>
        /// 根据SQL和查询参数获取对象列表
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="ht"></param>
        /// <returns></returns>
        public List<T> FetchList(string sql, NHashtable ht)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchList(sql, ht);
        }

        /// <summary>
        /// 根据实体对象获取对象列表
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public List<T> FetchList(T t)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchList(t);
        }

        /// <summary>
        /// 将DataRow数组转为List
        /// </summary>
        /// <param name="drs"></param>
        /// <returns></returns>
        public List<T> FetchList(DataRow[] drs)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchList(drs);
        }

        /// <summary>
        /// 根据存储过程获取LIST对象
        /// </summary>
        /// <param name="storeProcName">存储过程名称</param>
        /// <returns></returns>
        public List<T> FetchListWithStoreProc(string storeProcName)
        {
            DataTable dt = this.FetchDataTableWithStoreProc(storeProcName);
            if (dt == null)
            {
                return null;
            }

            return this.FetchList(dt.Select());
        }

        /// <summary>
        /// 根据存储过程获取LIST对象
        /// </summary>
        /// <param name="storeProcName">存储过程名称</param>
        /// <param name="ht">列表</param>
        /// <returns></returns>
        public List<T> FetchListWithStoreProc(string storeProcName, NHashtable ht)
        {
            DataTable dt = this.FetchDataTableWithStoreProc(storeProcName, ht);
            if (dt == null)
            {
                return null;
            }

            return this.FetchList(dt.Select());
        }

        /// <summary>
        /// 获取分页结果
        /// </summary>
        /// <param name="pagedQuery"></param>
        /// <returns></returns>
        public List<T> FetchPageList(T obj, PagedQuery pagedQuery)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchPageList(obj, pagedQuery);
        }

        /// <summary>
        /// 获取记录总数
        /// </summary>
        /// <param name="pagedQuery"></param>
        /// <returns></returns>
        public int FetchCount(T obj, PagedQuery pagedQuery)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchCount(obj, pagedQuery);
        }

        /// <summary>
        /// 获取记录总数
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int FetchCount(T obj)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).FetchCount(obj);
        }

        /// <summary>
        /// 执行带参数的存储过程
        /// </summary>
        /// <param name="storedProcName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public int RunProcedure(string storedProcName, IDataParameter[] parameters)
        {
            return DBHandlerFactory.GetHandler<T>(this.ConnectionString, this.DatabaseType).RunProcedure(storedProcName, parameters);
        }

        #endregion 泛型查询抽象方法
    }
}
